﻿using Microsoft.Expression.Drawing.Core;
using NPOI.SS.UserModel;
using Prism.Events;
using project.B12.application.Ioc;
using project.B12.IRepository;
using project.B12.Model.Enums;
using project.B12.Model.Models;
using project.B12.Model.Res;
using project.B12.Repository.Repository;
using project.B12.ViewModels;
using software.Common.MVVM;
using SQLitePCL;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;
using WPF.Controls;

namespace project.B12.application.ViewModels.Setting
{
    public class SIRViewModel:ObservableObject
    {
        private ISIRRepository _sIRRepository;

        private IBacteriaRepository _bacteriaRepository;

        private IMedicineRepository _medicineRepository;

        private List<Table_SIR>  _sirs=new List<Table_SIR>();

        //private BacteriaLevel _currentLevel;

        /// <summary>
        /// 当前指定层级的菌名
        /// </summary>
        private List<string> _currentBacteriaLevelNames;

        private int count;
        public int Count
        {
            get => count;
            set { count = value; CurrentPageChanged(); }
        }

        private int countPerPage = 13;
        public int CountPerPage
        {
            get => countPerPage;
            set { countPerPage = value; RaisePropertyChanged(); CurrentPageChanged(); }
        }

        private int currentPage;
        public int CurrentPage
        {
            get => currentPage;
            set { currentPage = value; RaisePropertyChanged(); CurrentPageChanged(); }
        }

        private ObservableCollection<Table_SIR> _currentSIRs;
        public ObservableCollection<Table_SIR> CurrentSIRs
        {
            get { return _currentSIRs; }
            set
            {
                _currentSIRs = value;
                this.RaisePropertyChanged();
            }
        }

        private List<string> _bacteriaLevelNames;
        /// <summary>
        /// SIR 指定菌的名称
        /// </summary>
        public List<string> BacteriaLevelNames
        {
            get { return _bacteriaLevelNames; }
            set
            {
                _bacteriaLevelNames = value;
                this.RaisePropertyChanged();
            }
        }

        private List<string> _medicineNames;
        /// <summary>
        /// 目标药物的名称
        /// </summary>
        public List<string> MedicineNames
        {
            get { return _medicineNames; }
            set
            {
                _medicineNames = value;
                this.RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 用户输入
        /// </summary>
        private string _nameInput;
        public string NameInput
        {
            get { return _nameInput; }
            set
            {
                _nameInput = value;
                QueryByBacteriaName(value);
                if (string.IsNullOrEmpty(value))
                    SelectQueriedBacteriaName = null;
                this.RaisePropertyChanged();
            }
        }

        private bool _isEnabled = true;
        public bool IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                _isEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private bool _cancelEnabled;
        public bool CancelEnabled
        {
            get { return _cancelEnabled; }
            set
            {
                _cancelEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        private string _selectQueriedBacteriaName { get; set; }
        /// <summary>
        /// 用户选择的下拉框菌
        /// </summary>
        public string SelectQueriedBacteriaName
        {
            get { return _selectQueriedBacteriaName; }
            set
            {
                _selectQueriedBacteriaName = value;
                this.RaisePropertyChanged();
            }
        }

        public ObservableCollection<BacteriaLevelItem> BacteriaLevelItems { get; set; }
        public class BacteriaLevelItem : ObservableObject
        {
            private int id;
            public int Id
            {
                get { return id; }
                set { id=value; this.RaisePropertyChanged(); }
            }

            private string? levelName;
            public string LevelName
            {
                get { return levelName;}
                set { levelName = value; this.RaisePropertyChanged(); }
            }
        }

        private List<BacteriaLevel> _levels;
        public List<BacteriaLevel> Levels
        {
            get { return _levels; }
            set
            {
                _levels = value;
                this.RaisePropertyChanged();
            }
        }

        private int _levelsIndex;
        public int LevelIndex
        {
            get { return _levelsIndex; }
            set
            {
                _levelsIndex = value;
                this.RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 选择的级别
        /// </summary>
        private BacteriaLevel _level;
        public BacteriaLevel Level
        {
            get { return _level; }
            set 
            { 
                _level = value;
                _currentBacteriaLevelNames = _bacteriaRepository.QueryByLevel(value);
                BacteriaLevelNames = _currentBacteriaLevelNames;
                this.RaisePropertyChanged(); 
            }
        }

        private string _bacteriaLevelNameInput;
        public string BacteriaLevelNameInput
        {
            get => _bacteriaLevelNameInput;
            set
            {
                _bacteriaLevelNameInput = value;
                _currentBacteriaLevelNames = _bacteriaRepository.QueryByLevel(Level);
                BacteriaLevelNames = _currentBacteriaLevelNames.Where(o=>o.Contains(value)).ToList();
                this.RaisePropertyChanged();
            }
        }

        private string _medicineNameInput;
        public string MedicineNameInput
        {
            get => _medicineNameInput;
            set
            {
                _medicineNameInput = value;
                MedicineNames=publicResourceViewModel.MedicineNames.Where(o => o.Contains(value)).ToList();
                this.RaisePropertyChanged();
            }
        }



        /// <summary>
        /// 查询下拉框的菌集合
        /// </summary>
        public ObservableCollection<string> QueriedBacteriaNames { get; set; }

        public ObservableCollection<BacteriaItem> BacteriaGroup { get; }

        public class BacteriaItem : ObservableObject
        {
            private bool _isSelected;
            public bool IsSelected
            {
                get { return this._isSelected; }
                set
                {
                    this._isSelected = value;
                    this.RaisePropertyChanged();
                }
            }

            private BacteriaLevel _name;
            public BacteriaLevel Name
            {
                get { return _name; }
                set
                {
                    _name = value;
                    this.RaisePropertyChanged();
                }
            }
        }

        public PublicResourceViewModel publicResourceViewModel { get; set; }

        //public RelayCommand<object> UpdateNames => new RelayCommand<object>(UpdateByBacteriaLevel);

        public RelayCommand Query => new RelayCommand(QueryIndistinct);

        public RelayCommand<object> Update => new RelayCommand<object>(UpdateSIR);

        public RelayCommand<object> Delete => new RelayCommand<object>(DeleteSIR);

        public RelayCommand Add => new RelayCommand(AddSIR);

        public RelayCommand Cancel => new RelayCommand(CancelSIR);

        private IEventAggregator _eventAggregator;

        public SIRViewModel(ISIRRepository sIRRepository,
            IBacteriaRepository bacteriaRepository,
            IMedicineRepository medicineRepository)
        {
            publicResourceViewModel = ViewModelLocator.PublicResourceViewModel;
            _sIRRepository = sIRRepository;
            _bacteriaRepository= bacteriaRepository;
            _medicineRepository = medicineRepository;
            Levels = new List<BacteriaLevel>();
            Levels.Add(BacteriaLevel.种);
            Levels.Add(BacteriaLevel.属);
            Levels.Add(BacteriaLevel.科);
            Levels.Add(BacteriaLevel.目);
            Levels.Add(BacteriaLevel.纲);
            Levels.Add(BacteriaLevel.门);
            Levels.Add(BacteriaLevel.界);
            Level = BacteriaLevel.种;

            Init();
        }

        public void Init()
        {
            _sirs = _sIRRepository.QueryAll();
            _sirs.ForEach(item => item.IsAdd = true);
            _currentBacteriaLevelNames = _bacteriaRepository.QueryByLevel(Level);
            BacteriaLevelNames = _currentBacteriaLevelNames;
            List<Table_bacteria> bacterias = _bacteriaRepository.QueryAllBacteria();
            foreach (var sir in _sirs)
            {
                string levelName = _bacteriaRepository.QueryNamesByID(sir.BacteriaLevelID, sir.BacteriaLevel);
                sir.CN_Name = levelName;
            }

            MedicineNames = _medicineRepository.QueryAllMedicine().Select(o=>o.CN_Name).ToList();
            List <Table_medicine> medicines = _medicineRepository.QueryAllMedicine();
            foreach (var sir in _sirs)
            {
                var medicine = _medicineRepository.QueryById(sir.MedicineID);
                if (medicine == null)
                    continue;
                sir.Target = medicine.CN_Name;
                sir.MedicineName = publicResourceViewModel.Language == LanguageEnum.Ch ? medicine.CN_Name : medicine.EN_Name;
                if(string.IsNullOrEmpty(sir.MedicineName))
                {
                    sir.MedicineName = string.IsNullOrEmpty(medicine.CN_Name) ? medicine.EN_Name : medicine.CN_Name;
                }
            }

            QueriedBacteriaNames = new ObservableCollection<string>();
            QueriedBacteriaNames.Add("全部");
            foreach (var sir in _sirs)
            {
                if (QueriedBacteriaNames.Contains(sir.CN_Name))
                    continue;
                QueriedBacteriaNames.Add(sir.CN_Name);
            }

            Count = _sirs.Count;
            CurrentSIRs = new ObservableCollection<Table_SIR>(_sirs.Take(CountPerPage));
            CurrentPage = 1;
        }

        private void CurrentPageChanged()
        {
            CurrentSIRs = new ObservableCollection<Table_SIR>(_sirs.Skip((CurrentPage - 1) * countPerPage).Take(countPerPage));
        }

        private void QueryByBacteriaName(string name)
        {
            if (name == "全部" || string.IsNullOrEmpty(name))
            {
                //CurrentSIRs = new ObservableCollection<Table_SIR>(_sirs);
                CurrentPageChanged();
                return;
            }  

            var sirs = _sirs.Where(o => o.CN_Name.Contains(name));
            CurrentSIRs = new ObservableCollection<Table_SIR>(sirs);
        }

        private void QueryIndistinct()
        {
            if (NameInput == "全部" || string.IsNullOrEmpty(NameInput))
            {
                //CurrentSIRs = new ObservableCollection<Table_SIR>(_sirs);
                CurrentPageChanged();
                return;
            }
            var sirs = _sirs.Where(o => o.CN_Name.Contains(NameInput)).ToList();
            CurrentSIRs = new ObservableCollection<Table_SIR>(sirs);
        }

        private void UpdateSIR(object sir)
        {
            Table_SIR temp = (Table_SIR)sir;
            List<int> ids = new List<int>();
            if (!ValidateId(temp, ref ids))
                return;
            if(!QueriedBacteriaNames.Contains(temp.CN_Name))
                QueriedBacteriaNames.Add(temp.CN_Name);

            //temp.BacteriaLevel = _currentLevel;
            temp.BacteriaLevelID = ids[0];
            temp.MedicineID = ids[1];
            temp.BacteriaLevel = Level;
            _sIRRepository.UpdateSIR(temp);
            _sirs.Where(o=>o.Id == temp.Id).ToList().First().IsUpdate = true;
            MessageBox.Show(Resources.UpdateSucess);
        }

        private void DeleteSIR(object sir)
        {
            MessageBoxResult result = MessageBox.Show(Resources.DeleteWaring, Resources.OperatorConfirm, MessageBoxButton.OKCancel, MessageBoxImage.Question);
            if (result == MessageBoxResult.Cancel)
                return;
            Table_SIR temp = (Table_SIR)sir;
            _sIRRepository.DeleteSIR(temp);
            _sirs.Remove(temp);
            QueriedBacteriaNames.Remove(temp.CN_Name);
            CurrentSIRs.Remove(temp);
            MessageBox.Show(Resources.DeleteSuccess);
        }

        private void AddSIR()
        {
            try
            {
                if (IsEnabled)
                {
                    IsEnabled = false;
                    CancelEnabled = true;
                    CurrentSIRs.Add(new Table_SIR() { BacteriaLevel=Level});
                    return;
                }
                var sir = CurrentSIRs.Where(o => o.IsAdd == false).ToList().First();
                List<int> ids = new List<int>();
                if (!ValidateId(sir, ref ids))
                    return;
                if (!QueriedBacteriaNames.Contains(sir.CN_Name))
                    QueriedBacteriaNames.Add(sir.CN_Name);

                sir.BacteriaLevel = Level;
                sir.BacteriaLevelID = ids[0];
                sir.MedicineID = ids[1];
                _sIRRepository.AddSIR(sir);
                sir.IsAdd = true;
                _sirs.Add(sir);
                IsEnabled = true;
                CancelEnabled = false;
                MessageBox.Show(Resources.AddSuccess);
            }
            catch (Exception ex)
            {
                WPF.Controls.Message.Push(Resources.AddFailure, MessageBoxImage.Warning);
            }
        }
        private void CancelSIR()
        {
            if (!IsEnabled)
            {
                CurrentSIRs.RemoveLast();
                IsEnabled = true;
            }
        }

        public bool ValidateId(Table_SIR sir,ref List<int> ids)
        {
            int medicineId = _medicineRepository.QueryIdByName(sir.MedicineName);
            if (medicineId == 0)
            {
                MessageBox.Show(Resources.MedicineInexistence);
                return false;
            }

            ids = new List<int>();
            
            int bacyeriaLevelId1 = _bacteriaRepository.QueryIdByLevelName(Level, sir.CN_Name);
            //int bacyeriaLevelId2 = _bacteriaRepository.QueryIdByLevelName(_currentLevel, sir.CN_Name);
            if (bacyeriaLevelId1 == 0)
            {
                //if(bacyeriaLevelId2 == 0)
                //{
                    MessageBox.Show(Resources.BacteriaInexistence);
                //    return false;
                //}
                //ids.Add(bacyeriaLevelId2);

                return false;
            }
            else
                ids.Add(bacyeriaLevelId1);
            ids.Add(medicineId);
            return true;
        }
    }
}
